/*
 * StreamThread.java
 * Created on Apr 26, 2005 12:42:15 PM
 */
package com.alsutton.jabber;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Hashtable;

import com.alsutton.xmlparser.XMLEventListener;
import com.alsutton.xmlparser.XMLParser;

/**
 * @author Andry
 * The StreamThread.java class provides
 *
 */
public class StreamThread implements Runnable, XMLEventListener {
	  /**
	   * The threads run method. Handles the parsing of incomming data in its
	   * own thread.
	   */
    
    /**
     * The input stream from the server.
     */

    private InputStream inpStream;

    /**
     * The dispatcher thread.
     */

    private JabberDataBlockDispatcher dispatcher;
    
    public StreamThread(InputStream inpStream, JabberDataBlockDispatcher dispatcher) {
        this.inpStream = inpStream;
        this.dispatcher = dispatcher;
    }
    
	 public void run() {
	    try
	    {
	      InputStreamReader inSource = new InputStreamReader( inpStream );
	      XMLParser parser = new XMLParser( this );
	      parser.parse( inSource );
	      dispatcher.broadcastTerminatedConnection( null );
	    }
	    catch( Exception e )
	    {
	      dispatcher.broadcastTerminatedConnection(e);
	    }
	 }
	
	  /**
	   * The current class being constructed.
	   */
	
	  private JabberDataBlock currentBlock;
	
	  /**
	   * Method called when an XML tag is started in the stream comming from the
	   * server.
	   *
	   * @param name Tag name.
	   * @param attributes The tags attributes.
	   */
	
	  public void tagStarted( String name, Hashtable attributes )
	  {
	    if ( name.equals( "stream:stream" ) ) {
	      dispatcher.broadcastBeginConversation();
	    } else {
	      currentBlock = new JabberDataBlock( name, currentBlock, attributes );
	    }
	  }
	
	  /**
	   * Method called when some plain text is encountered in the XML stream
	   * comming from the server.
	   *
	   * @param text The plain text in question
	   */
	
	  public void plaintextEncountered( String text )
	  {
	    if( currentBlock != null )
	    {
	      currentBlock.addText( text );
	    }
	  }
	
	  /**
	   * The method called when a tag is ended in the stream comming from the
	   * server.
	   *
	   * @param name The name of the tag that has just ended.
	   */
	
	  public void tagEnded( String name )
	  {
	    if( currentBlock == null ) {
	        if (name.equals("stream:stream")) {
	            dispatcher.broadcastJabberDataBlock(new JabberDataBlock("xms:server_close_stream", null, null));
	        }
	      return;
	    }
	
	    JabberDataBlock parent = currentBlock.getParent();
	    if( parent == null )
	      dispatcher.broadcastJabberDataBlock( currentBlock );
	    else
	      parent.addChild( currentBlock );
	    currentBlock = parent;
	  }
}
